package com.mswyt.utils.msConverts;

import java.lang.reflect.Field;
import java.util.*;

/**
 * 实体类相关的都方法
 *
 * @ClassName: MsEntityUtils
 * @Description: 实体类工具类
 */
public class MsEntityUtils {
    /**
     * 检查两个实体字段值是否一直。
     *
     * @param newT
     * @param oldT
     * @return
     * @author mashuai
     */

    public static <T> Boolean checkEntityValIsSame(T newT, T oldT) throws Exception {
        Class<?> oldClass = oldT.getClass();
        for (Field nF : newT.getClass().getDeclaredFields()) {
            nF.setAccessible(true);
            //新值
            Object nV = nF.get(newT);
            String nfName = nF.getName();
            Field oF = oldClass.getDeclaredField(nfName);
            oF.setAccessible(true);
            //旧值
            Object oV = oF.get(oldT);
            //如果两个值不相同
            if (!String.valueOf(nV).equals(String.valueOf(oV))) {
                return false;
            }
        }
        return false;
    }

    /**
     * 获取两个相同实体类中不同字段的值
     *
     * @param newT 新实体类
     * @param oldT 旧的实体类
     * @return {"newVal":{},"oldVal":{}}
     * @author mashuai
     */

    public static <T> Map<String, Map<String, Object>> getEntityNoSameVal(T newT, T oldT) throws Exception {
        Map<String, Map<String, Object>> map = new HashMap<>();
        Map<String, Object> newValMap = new HashMap<>();
        Map<String, Object> oldValMap = new HashMap<>();
        Class<?> oldClass = oldT.getClass();
        for (Field nF : newT.getClass().getDeclaredFields()) {
            nF.setAccessible(true);
            //新值
            Object nV = nF.get(newT);
            String nfName = nF.getName();
            Field oF = oldClass.getDeclaredField(nfName);
            oF.setAccessible(true);
            //旧值
            Object oV = oF.get(oldT);
            //如果两个值不相同
            if (!String.valueOf(nV).equals(String.valueOf(oV))) {
                newValMap.put(nfName, nV);
                oldValMap.put(nfName, oV);
            }
        }
        //如果没有新值，直接返回空集合
        if (newValMap.size() == 0 || oldValMap.size() == 0) return map;
        map.put("newVal", newValMap);
        map.put("oldVal", oldValMap);
        return map;
    }

    /**
     * 获取两个实体类不相同的字段
     * @param clazz1
	 * @param clazz2
     * @return
     * @author mashuai
     */

    public static Set<String> getDifferentFields(Class<?> clazz1, Class<?> clazz2) {
        return sameOrDifferentField(clazz1, clazz2, false);
    }

    /**
     * 获取两个实体类相同的字段
     * @param clazz1
     * @param clazz2
     * @return
     * @author mashuai
     */
    public static Set<String> getSameFields(Class<?> clazz1, Class<?> clazz2) {
        return sameOrDifferentField(clazz1, clazz2, true);
    }
    private static Set<String> sameOrDifferentField(Class<?> clazz1, Class<?> clazz2, boolean isSame) {
        Field[] fields1 = clazz1.getDeclaredFields();
        Field[] fields2 = clazz2.getDeclaredFields();
        Set<String> sameFields = new HashSet<>();
        Set<String> differentFields = new HashSet<>();
        for (Field field1 : fields1) {
            for (Field field2 : fields2) {
                if (field1.getName().equals(field2.getName())) {
                    sameFields.add(field1.getName());
                }
            }
            if (!sameFields.contains(field1.getName())) {
                differentFields.add(field1.getName());
            }
        }
        for (Field field2 : fields2) {
            if (!sameFields.contains(field2.getName())) {
                differentFields.add(field2.getName());
            }
        }
        return isSame ? sameFields : differentFields;
    }


}
